package com.combetter.changxing.ui.fragment;

import android.Manifest;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.widget.LinearLayoutManager;
import android.view.Gravity;
import android.view.View;

import com.clj.fastble.BleManager;
import com.clj.fastble.data.BleDevice;
import com.jakewharton.rxbinding2.view.RxView;
import com.tbruyelle.rxpermissions2.RxPermissions;
import com.combetter.changxing.MyApp;
import com.combetter.changxing.R;
import com.combetter.changxing.adapter.FacilityAdapter;
import com.combetter.changxing.adapter.FacilityListAdapter;
import com.combetter.changxing.bluetooth.FacilityClient2;
import com.combetter.changxing.databinding.FragmentFacilityBinding;
import com.combetter.changxing.db.entity.Facility;
import com.combetter.changxing.model.EventMessage;
import com.combetter.changxing.ui.base.BleScanFragment;
import com.combetter.changxing.ui.dialog.FacilityRechristenDialog;
import com.combetter.changxing.ui.dialog.LoadingDialog;
import com.combetter.changxing.util.LogUtil;
import com.combetter.changxing.util.ToastUtils;
import com.combetter.changxing.viewmodel.FacilityViewModel;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.List;

import static com.combetter.changxing.bluetooth.FacilityClient2.AUTH_NONE;

/**
 * 类名  ElectronicPipe
 * 作者  tlfx: Sean.guo
 * 日期  2019/4/4 15:33
 */
public class FacilityFragmentReWrite extends BleScanFragment<FragmentFacilityBinding, FacilityViewModel>
        implements FacilityAdapter.FacilityInterface, FacilityListAdapter.FacilityListInterface {
    public static int RECHRISTEN_CODDE = 400;
    private FacilityAdapter mAlreadyAdapter;
    private FacilityListAdapter mListAdapter;
    private RxPermissions rxPermissions;

    private final static long SCAN_PERIOD = 10 * 1000;

    private boolean isFlag = true;
    private LoadingDialog loadingDialog;


    @Override
    public int setLayout() {
        EventBus.getDefault().register(this);
        return R.layout.fragment_facility;
    }

    @Override
    public Class createViewModel() {
        return FacilityViewModel.class;
    }

    @Override
    public void init() {
        super.init();
        mAlreadyAdapter = new FacilityAdapter(mContext, null);
        mBinding.recycler.setLayoutManager(new LinearLayoutManager(mContext, LinearLayoutManager.VERTICAL, false));
        mBinding.recycler.setAdapter(mAlreadyAdapter);
        mAlreadyAdapter.setFacilityClickListener(this);

        mListAdapter = new FacilityListAdapter(null);
        mBinding.listRecycler.setLayoutManager(new LinearLayoutManager(mContext, LinearLayoutManager.VERTICAL, false));
        mBinding.listRecycler.setAdapter(mListAdapter);
        mListAdapter.setFacilityListClickListener(this);

        loadingDialog = new LoadingDialog(mContext);
        rxPermissions = new RxPermissions(getActivity());

        mViewModel.upLoadDBDevice(getActivity());
    }


    @Override
    public void loadData() {
        /**
         *  扫描设备
         */
        RxView.clicks(mBinding.tvScan)
                .compose(rxPermissions.ensure(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.BLUETOOTH))
                .subscribe(aBoolean -> {
                    if (aBoolean) {
                        scan();
                    } else {
                        ToastUtils.error("没有开启定位权限");
                    }
                });
    }

    /**
     * 加载本地数据库
     */
    private void setData() {
        mAlreadyAdapter.clearAllData();
        List<Facility> mFacility = MyApp.getInstance().getFacilityInfo();
        if (mFacility != null && mFacility.size() > 0) {
            mAlreadyAdapter.setNewData(mFacility);
            mBinding.tvFacilityName.setGravity(Gravity.LEFT);
            mBinding.tvFacilityName.setText("已配对设备");
        } else {
            mBinding.tvFacilityName.setGravity(Gravity.CENTER);
            mBinding.tvFacilityName.setText("当前暂无设备");
            mBinding.radar.setSearching(false);
        }
    }

    /**
     * 扫描效果
     */
    public void scan() {
        //开始扫描设备
        mBinding.flRadar.setVisibility(View.VISIBLE);
        mBinding.radar.setSearching(true);
        mListAdapter.getData().clear();
        mListAdapter.notifyDataSetChanged();
        isFlag = true;
        ToastUtils.showToastShort("搜索过程中靠近设备进行连接");
        mHandler.postDelayed(() -> {
            scanLeDevice(true);
            mHandler.postDelayed(scanTask, SCAN_PERIOD);
        }, 0);
    }


    private Runnable scanTask = new Runnable() {
        @Override
        public void run() {
            scanLeDevice(false);
            if (mListAdapter.getData().size() == 0) {
                if (FacilityClient2.mConnectState != BluetoothGatt.STATE_CONNECTED) {
                    ToastUtils.showToast("没有搜索到设备");
                }
            } else {
                mListAdapter.notifyDataSetChanged();
            }
            mBinding.radar.setSearching(false);
            mBinding.flRadar.setVisibility(View.GONE);
        }
    };

    @Override
    public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
        addDevice(device, rssi);
    }

    /**
     * 过滤把符合要求的设备添加到列表
     *
     * @param device
     */

    private void addDevice(BluetoothDevice device, int rssi) {
        if (device != null && device.getName() != null && device.getName().startsWith("HNB")) {
            LogUtil.e("" + device.getName() + ", " + device.getAddress());
            for (final Facility advDevice : mAlreadyAdapter.getData()) {
                if (device.getAddress().equals(advDevice.getFacilityAddress()) && FacilityClient2.mConnectState != BluetoothGatt.STATE_CONNECTED && FacilityClient2.mConnectState != BluetoothGatt.STATE_CONNECTING) {
                    mAlreadyAdapter.notifyDataSetChanged();
                    break;
                }
            }

            for (final BluetoothDevice advDevice : mListAdapter.getData()) {
                if (device.getAddress().equals(advDevice.getAddress()) && FacilityClient2.mConnectState != BluetoothGatt.STATE_CONNECTED && FacilityClient2.mConnectState != BluetoothGatt.STATE_CONNECTING) {
                    LogUtil.e("---------scan:" + device.getName() + "  mac:" + device.getAddress() + "  rssi:" + rssi);
                    mListAdapter.notifyDataSetChanged();
                    if (rssi > -30 && isFlag) {
                        isFlag = false;
                        stopAndDeal();
                        nearConnect(device);
                        break;
                    }
                    return;
                }
            }

            getActivity().runOnUiThread(() -> {
                BluetoothDevice temp = getDealList(device, mAlreadyAdapter.getData());//筛选是否在已配对列表中
                if (temp != null && !mListAdapter.getData().contains(temp)) {//不在配对列表中也不在搜索列表中
                    mListAdapter.addData(device);
                    mListAdapter.notifyDataSetChanged();
                } else {
                    mListAdapter.notifyDataSetChanged();
                }
            });
        }
    }

    /**
     * 如已在配对列表中，则不显示在搜素列表上
     *
     * @param device
     * @param facilityModels
     * @return
     */
    private BluetoothDevice getDealList(BluetoothDevice device, List<Facility> facilityModels) {
        BluetoothDevice tempDevice = device;
        for (Facility facilityModel : facilityModels) {
            if ((device != null || device.getAddress() != null) && device.getAddress().equals(facilityModel.getFacilityAddress())) {
                tempDevice = null;
                break;
            }
        }
        return tempDevice;
    }

    /**
     * 近场连接设备
     *
     * @param device
     */
    private void nearConnect(BluetoothDevice device) {
        if (loadingDialog != null) {
            loadingDialog.setMsg("鉴权中...");
            loadingDialog.show();
        }
        Facility facility = MyApp.getInstance().getDatabase().facilityDao().findByMac(device.getAddress());
        if (facility == null || (facility != null && !facility.getUid().equals(MyApp.getInstance().getUserInfo().getUid()))) {
            facility = new Facility();
            facility.setFacilityName(device.getName());
            facility.setUid(MyApp.getInstance().getUserInfo().getUid());
            facility.setFacilityAddress(device.getAddress());
            MyApp.getInstance().getDatabase().facilityDao().insertAllOrSingle(facility);
        }
        setData();
        if (mListAdapter.getData() != null && mListAdapter.getData().contains(device)) {
            mListAdapter.getData().remove(device);
            mListAdapter.notifyDataSetChanged();
        }
        FacilityClient2.getClient().connect(device.getAddress());
        mViewModel.insertFacility(getActivity(), device.getAddress(), device.getName(), 1, 0);
    }

    /**
     * 停止扫描
     */
    private void stopAndDeal() {
        mHandler.removeCallbacks(scanTask);
        scanLeDevice(false);
        mBinding.listLayout.setVisibility(View.VISIBLE);
        mListAdapter.notifyDataSetChanged();
        mBinding.radar.setSearching(false);
        mBinding.flRadar.setVisibility(View.GONE);
    }


    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
            }
        }
    };


    /**
     * 点击连接设备
     *
     * @param item
     */
    @Override
    public void viewConnect(Facility item) {
        boolean someConnected = false;
        List<BleDevice> bleDevices = BleManager.getInstance().getAllConnectedDevice();
        for (BleDevice bean : bleDevices) {
            if (BleManager.getInstance().isConnected(bean) && !item.getFacilityAddress().equals(bean.getMac())) {
                someConnected = true;
                break;
            }
        }
        if (someConnected) {
            ToastUtils.error("已连接设备，请断开后再进行操作");
            return;
        }
        if (loadingDialog != null) {
            loadingDialog.setMsg("鉴权中...");
            loadingDialog.show();
        }
        if (!BleManager.getInstance().isConnected(item.getFacilityAddress())) {
            FacilityClient2.mAuthStatu = AUTH_NONE;
        }
        FacilityClient2.getClient().connect(item.getFacilityAddress());
        FacilityClient2.reConnectTimes = 0;
    }

    /**
     * 断开设备连接设备
     *
     * @param item
     */
    @Override
    public void viewDisconnect(Facility item) {
        FacilityClient2.mAuthStatu = AUTH_NONE;
        BleManager.getInstance().disconnectAllDevice();
        FacilityClient2.getClient().disconnect();
        MyApp.getInstance().resetUserInfo();
    }

    /**
     * 重命名
     *
     * @param item
     */
    @Override
    public void viewRename(Facility item) {
        FacilityRechristenDialog dialog = new FacilityRechristenDialog();
        Bundle bundle = new Bundle();
        bundle.putString("facilityName", item.getFacilityName());
        bundle.putString("identifierId", item.getFacilityAddress());
        bundle.putInt("mid", item.getMid());
        dialog.setArguments(bundle);
        dialog.setTargetFragment(FacilityFragmentReWrite.this, RECHRISTEN_CODDE);
        dialog.show(getActivity().getSupportFragmentManager(), "");
    }

    /**
     * 取消配对
     *
     * @param item
     * @param isConnect
     */
    @Override
    public void viewCancelMate(Facility item, boolean isConnect) {
        if (isConnect) {
            BleManager.getInstance().disconnectAllDevice();
            FacilityClient2.getClient().disconnect();
        }
        MyApp.getInstance().resetUserInfo();
        MyApp.getInstance().getDatabase().facilityDao().deleteFacility(item);
        setData();
    }

    /**
     * 添加配对设备
     *
     * @param item
     */
    @Override
    public void viewAdd(BluetoothDevice item) {
        Facility facility = MyApp.getInstance().getDatabase().facilityDao().findByMac(item.getAddress());
        if (facility == null || (facility != null && !facility.getUid().equals(MyApp.getInstance().getUserInfo().getUid()))) {
            facility = new Facility();
            facility.setFacilityName(item.getName());
            facility.setUid(MyApp.getInstance().getUserInfo().getUid());
            facility.setFacilityAddress(item.getAddress());
            MyApp.getInstance().getDatabase().facilityDao().insertAllOrSingle(facility);
            if (mListAdapter.getData() != null && mListAdapter.getData().contains(item)) {
                mListAdapter.getData().remove(item);
                mListAdapter.notifyDataSetChanged();
            }
            ToastUtils.success("添加成功!");
        }
        setData();
        mViewModel.insertFacility(getActivity(), item.getAddress(), item.getName(), 1, 0);
    }


    @Subscribe(threadMode = ThreadMode.MAIN)
    public void getEventData(EventMessage message) {
        switch (message.getType()) {
            // 蓝牙连接成功
            case "BleAuthSuccess":
                mListAdapter.clearAllData();
                setData();
//                ToastUtils.showToastShort("蓝牙连接成功");
                if (loadingDialog != null) {
                    loadingDialog.dismiss();
                }
                break;
            //已配对的设备列表回调
            case "connectFail":
                mAlreadyAdapter.notifyDataSetChanged();
                if (loadingDialog != null) {
                    loadingDialog.dismiss();
                }
                break;
            case "onDisConnected":
                setData();
                mListAdapter.getData().clear();
                mListAdapter.notifyDataSetChanged();
                if (loadingDialog != null) {
                    loadingDialog.dismiss();
                }
                break;
            case "AuthFail":
                mAlreadyAdapter.notifyDataSetChanged();
                if (loadingDialog != null) {
                    loadingDialog.dismiss();
                }
                break;
        }

    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        try {
            if (!hidden) {
                setData();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //重命名
        if (requestCode == RECHRISTEN_CODDE) {
            int mid = data.getIntExtra("mid", 0);
            String facilityName = data.getStringExtra("facilityName");
            String identifierId = data.getStringExtra("identifierId");
            List<Facility> facilitys = MyApp.getInstance().getDatabase().facilityDao().findByUid(MyApp.getInstance().getUserInfo().getUid());
            for (Facility facility:facilitys) {
                if (facility.getFacilityAddress().equals(identifierId)){
                    facility.setFacilityName(facilityName);
                    MyApp.getInstance().getDatabase().facilityDao().update(facility);
                }
            }
            setData();

            byte[] value = facilityName.getBytes();
            byte[] data0 = new byte[16];
            for (int i = 0; i < 16; i++) {
                if (value.length - 1 < i) {
                    data0[i] = 0x00;
                } else {
                    data0[i] = value[i];
                }
            }
            FacilityClient2.getClient().sendName(data0);
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        if (MyApp.getInstance().getFacilityInfo() != null) {
            BleManager.getInstance().destroy();
        }
        if (EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this);
        }
        if (loadingDialog != null) {
            loadingDialog.dismiss();
            loadingDialog = null;
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        if (loadingDialog != null) {
            loadingDialog.dismiss();
        }
    }
}
